package com.dg.acb.utils;

import android.content.ContentProviderOperation;
import android.content.ContentProviderResult;
import android.content.ContentResolver;
import android.content.OperationApplicationException;
import android.net.Uri;
import android.os.RemoteException;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class BatchOperation {
    public static final int BATCH_OP_COUNT = 100;
    private final ContentResolver mResolver;
    private final Map<String, ArrayList<ContentProviderOperation>> mOperationMap;

    public BatchOperation(ContentResolver resolver) {
        mResolver = resolver;
        mOperationMap = new HashMap<String, ArrayList<ContentProviderOperation>>();
    }

    public synchronized Set<String> getAuthoritys(){
        return mOperationMap.keySet();
    }

    protected synchronized void clearAuthoritys(){
        mOperationMap.clear();
    }

    public int size() {
        int size = 0;
        for (ArrayList<ContentProviderOperation> ops : mOperationMap.values()) {
            size += ops.size();
        }
        return size;
    }

    public boolean batchSizeEnough() {
        return size() > BATCH_OP_COUNT;
    }

    public synchronized  int getOperationSize(String authority) {
        ArrayList<ContentProviderOperation> ops = mOperationMap.get(authority);
        return ops == null ? 0 : ops.size();
    }

    public synchronized int add(ContentProviderOperation cpo) {
        if (cpo != null) {
            String authority = cpo.getUri().getAuthority();
            ArrayList<ContentProviderOperation> ops = mOperationMap.get(authority);
            if (ops == null) {
                ops = new ArrayList<ContentProviderOperation>();
                mOperationMap.put(authority, ops);
            }
            ops.add(cpo);
            return ops.size()-1;
        }
        return -1;
    }

    protected synchronized List<Uri> innerexecute(String authority) {
         ArrayList<ContentProviderOperation> ops = mOperationMap.get(authority);
        if (ops .size() == 0) {
            return Collections.emptyList();
        }
        List<Uri> resultUris = new ArrayList<Uri>();
        // Apply the mOperations to the content provider
        try {
            ContentProviderResult[] results = mResolver.applyBatch(
                    authority,
                    ops);
            if ((results != null) && (results.length > 0)){
                for (ContentProviderResult result : results) {
                    resultUris.add(result.uri);
                }
            }
        } catch (final OperationApplicationException e1) {
            LogUtil.e("storing data failed1" + e1);
        } catch (final RemoteException e2) {
            LogUtil.e("storing data failed2" + e2);
        }
        ops.clear();
        return resultUris;
    }

    public void execute() {
        for (String authority : getAuthoritys()) {
            innerexecute(authority);
        }
    }
}
